<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <button id="button"></button>
<script>
// 高阶函数实现AOP--面向切面编程
Function.prototype.before = function(beforefn) {
  // 保存原函数的引用
  let __self = this;
  // 返回包含了原函数和新函数的"代理"函数
  return function() {
    // 执行新函数，保证 this不被劫持
    beforefn.apply(this, arguments);
    // 执行原函数，保证 this不被劫持
    return __self.apply(this, arguments);
  }
};
Function.prototype.after = function(afterfn) {
  let __self = this;
  return function() {
    let ret = __self.apply(this, arguments);
    afterfn.apply(this, arguments);
    return ret;
  }
};
// document.getElementById = document.getElementById.before(() => alert(1))
// let button = document.getElementById('button')
// console.log('button');

// 将原函数和新函数作为参数传入 before|after 方法

let before = function(fn, beforefn) {
  return function() {
    beforefn.apply(this, arguments);
    return fn.apply(this, arguments);
  }
}
let a = before(
  function() { alert(3) },
  function() { alert(2) },
)
a = before(a, function() { alert(1)})
a()
</script>
</body>
</html>